<?php

namespace App\HttpController\Api;

use App\Component\DeviceIdentity\DeviceUser;
use App\Core\Exception\DefaultException;
use App\Lib\Mongodb\Mongodb;
use App\Util\UserIdentityHelper;
use EasySwoole\Component\Di;
use Exception;

class BaseController extends \App\Core\BaseController
{
    protected $_checkAuth = true;

    protected function onRequest(?string $action): ?bool
    {
        if (($res = parent::onRequest($action))) {
            $device = new \App\Component\User(\App\Component\DeviceIdentity\DeviceUser::class);
            //判断是否登陆
            //            $user = new BackendUser();
            //把对象放到DI容器中
            Di::getInstance()->set('user', $device);
            //开启debug时，不需要校验登陆，直接取sadmin数据
            if (!$device->isLogin() && !empty($this->request()->getHeader('debug-device')[0])) {
                $deviceModel = \App\Component\DeviceIdentity\DeviceUser::findIdentity($this->request()->getHeader('debug-device')[0]);
//                $device->login($deviceModel);
//                return $res;
            }

            //未登陆时，判断是否为登陆接口，不是则提示需要登陆操作
            $serverParams = $this->request()->getServerParams();
            //无需权限路由
            $no_auth = [
                '/api/member/register',    //用户注册
                '/api/member/login',    //用户登录
            ];

            if ($this->_checkAuth && !in_array(strtolower($serverParams['request_uri']), $no_auth)) {
                //判断是否存在jwt-token数据
                if ($this->request()->hasHeader('jwt-token')) {
                    //通过jwt登陆
                    $jwtToken = $this->request()->getHeader('jwt-token');
                    $device->loginByJwt($jwtToken[0]);
                }
                //判断是否已登陆
                if ($device->isLogin()) {
                    $deviceIdentity = $device->getIdentity();
                    //登陆后的权限等校验操作
                    if (!(self::checkBaseAuth($deviceIdentity) && $this->checkSelfAuth())) {
                        throw new DefaultException('该接口无权限', 1002);
                    }
                } else {
                    throw new DefaultException('请先登陆', 1001);
                }
            } else {
//                var_dump(123123123123);

                //尝试登录一下
                try {
//                    if ($this->request()->hasHeader('jwt-token')) {
//                        //通过jwt登陆
//                        $jwtToken = $this->request()->getHeader('jwt-token');
//                        $device->loginByJwt($jwtToken[0]);
//                    }
                } catch (Exception $e) {
                }
            }
        }
        return $res;
    }

    protected function afterAction(?string $actionName): void
    {
        $jwtToken = '';
        /** @var \App\Component\User $user */
        if (($user = Di::getInstance()->get('user')) !== null && $user->isLogin()) {
            $jwtToken = $user->generalJwtToken();
            $this->response()->withHeader('jwt-token', $jwtToken);
        }
        $namespaceParts = explode('\\', __NAMESPACE__);
        $lastNamespacePart = end($namespaceParts);
        $this->sysLog($lastNamespacePart, $jwtToken);

        parent::afterAction($actionName);
    }

    /**
     * 检查用户权限 - 路由检查
     * @param DeviceUser $deviceIdentity
     * @return bool
     */
    private function checkBaseAuth($deviceIdentity)
    {
        $request = $this->request();

        //获取接口请求地址
        $path = $request->getUri()->getPath();

        //切割
        $path = strtolower($path);

        //公共接口无需校验权限
        $no_auth = [];
        foreach ($no_auth as $item) {
            // 通过位运算来比较是否存在该路由
            if (($path & $item) === $item) {
                return true;
            }
        }

        //校验权限
        if ($deviceIdentity->checkAuth($path)) {
            return true;
        }

        //请求方式为get，方法为index,info,dict3个类型，默认为上级
        $method = $request->getMethod();
        if ($method == 'GET') {
            //当前请求方法
            $arr = explode('/', $path);
            $action = end($arr);

            if (in_array($action, ['info', 'dict'])) {
                //替换方法名
                array_pop($arr);
                array_push($arr, 'index');
            }

            //组装标识
            $auth = implode('/', $arr);

            //判断当前是否存在着权限
            if ($deviceIdentity->checkAuth($auth)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 调用当前控制器的权限检查 - 数据相关
     * @return bool
     */
    public function checkSelfAuth()
    {
        if (method_exists($this, '_checkAuth')) {
            return $this->_checkAuth();
        } else {
            return true;
        }
    }

}
